#include "head.h"
#include "lua_eventfd.h"

/*
    usage:  create()
    paras:  \
    return: [tfd]、[nil,errno]
*/
static int l_eventfd_create(lua_State *L) {
    int fd = eventfd(0, 0);
    if (fd == -1) {
        lua_pushnil(L);
        lua_pushstring(L, strerror(errno));
        return 2;
    }
    lua_pushinteger(L, fd);
    return 1;
}

/*
    usage:  read(tfd)
    paras:  tfd
    return: [true]、[false]
*/
static int l_eventfd_read(lua_State *L) {
    int fd = luaL_checkinteger(L, 1);
    uint64_t _;
    if (read(fd, &_, sizeof(uint64_t)) != sizeof(uint64_t)) {
        lua_pushboolean(L, false);
        return 1;
    }
    lua_pushboolean(L, true);
    return 1;
}

/*
    usage:  write(tfd)
    paras:  tfd
    return: \
*/
static int l_eventfd_write(lua_State *L) {
    int fd = luaL_checkinteger(L, 1);
    uint64_t _ = 1;
    write(fd, &_, sizeof(uint64_t));
    return 0;
}

/*
    usage:  close(tfd)
    paras:  tfd
    return: \、[errno]
*/
static int l_eventfd_close(lua_State *L) {
    int fd = luaL_checkinteger(L, 1);
    if (close(fd)) {
        lua_pushstring(L, strerror(errno));
        return 1;
    }
    return 0;
}

int lua_lib_eventfd(lua_State *L) {
    static const struct luaL_Reg l[] = {
        { "create", l_eventfd_create },
        { "read", l_eventfd_read },
        { "write", l_eventfd_write },
        { "close", l_eventfd_close }, 
        { NULL, NULL }
    };
    luaL_newlib(L, l);
    return 1;
}